package token

import (
	"fmt"
	"ginweb/model/error_admin"
	jwt "github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	"time"
)

func AuthMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		fmt.Println("进行token验证....")
		//认证成功做跳转
		c.Next()
	}
}

// 验证jwt
func AuthToken(c *gin.Context) {
	fmt.Println("进行token验证....")
	content, err := ValidateToken(c)
	if err != nil {
		fmt.Println(err)
		error_admin.SendRsp(c, error_admin.AuthError, content)
		c.Abort()
		fmt.Println("token 验证失败")
		return
	}
	// 验证通过，跳到下一个函数处理
	c.Set("UserId", content.Id)
	c.Set("UserName", content.UserName)
	c.Next()
}

type TokenContext struct {
	Id       uint64
	UserName string
}

// 生成token
func Sign(c TokenContext, secret string) (tokenString string, err error) {
	if secret == "" {
		secret = viper.GetString("jwt_secret")
	}
	// 生成token内容
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"id":       c.Id,
		"username": c.UserName,
		"exp":      time.Now().Unix() + viper.GetInt64("expir"), // 过期时间
	})
	// 生成token
	tokenString, err = token.SignedString([]byte(secret))
	return
}

// 验证token
func ValidateToken(c *gin.Context) (*TokenContext, error) {
	// 获取客户端传递的token
	tokenstring := c.Request.Header.Get("Authorization")
	if tokenstring == "" {
		return nil, fmt.Errorf("token为空！")
	}

	// 解析token
	token, err := jwt.Parse(tokenstring, secretFunc)
	if err != nil {
		return nil, err
	}

	if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
		ctx := &TokenContext{
			Id:       uint64(claims["id"].(float64)),
			UserName: claims["username"].(string),
		}
		return ctx, nil
	}

	return nil, fmt.Errorf("无法解析!")
}

func secretFunc(token *jwt.Token) (interface{}, error) {
	return []byte(viper.GetString("jwt_secret")), nil
}
